package com.mali.malibackendproduct.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mali.backendcommon.common.Result;
import com.mali.backendcommon.constant.AuthenticationConstant;
import com.mali.backendcommon.constant.MessageConstant;
import com.mali.backendcommon.exception.ShuMaException;
import com.mali.backendcommon.rpc.ProductService;
import com.mali.backendcommon.rpc.UserService;
import com.mali.backendcommon.util.BloomUtil;
import com.mali.backendcommon.util.UserContext;
import com.mali.malibackendmodel.dto.ProductAddDTO;
import com.mali.malibackendmodel.dto.ProductEditDTO;
import com.mali.malibackendmodel.dto.ProductQueryDTO;
import com.mali.malibackendmodel.pojo.*;
import com.mali.malibackendmodel.vo.PageVO;
import com.mali.malibackendmodel.vo.ProductDetailsQueryVO;
import com.mali.malibackendmodel.vo.ProductQueryVO;
import com.mali.malibackendmodel.vo.UserVO;
import com.mali.malibackendproduct.mapper.PriceMapper;
import com.mali.malibackendproduct.mapper.ProductMapper;
import com.mali.malibackendproduct.mapper.ProxyProductMapper;
import com.mali.malibackendproduct.mapper.ServerMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import com.mali.malibackendproduct.service.PriceService;
import com.mali.malibackendproduct.service.ScratchpadService;
import com.mali.malibackendproduct.service.ServerService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.amqp.core.Message;

import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
* @author 132993
* @description 针对表【product(商品)】的数据库操作Service实现
* @createDate 2024-06-16 10:48:34
*/
@Service
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product>
    implements ProductService{
    @Autowired
    private ProductMapper productMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ProxyProductMapper proxyMapper;

    @Autowired
    private ServerMapper serverMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private PriceMapper priceMapper;

    @Autowired
    private PriceService priceService;

    @Autowired
    private ScratchpadService scratchpadService;

    @Autowired
    private ServerService serverService;

    @Autowired
    private UserService userService;
    /**
     * @author 吴键霏
     * @description 用于日志权限认证
     * @createDate 2024-06-19 19:17:30
     */
    @Override
    public boolean haveAuthority(Long productId, Long userId) {
        Long count = productMapper.selectCount(new LambdaQueryWrapper<Product>().eq(Product::getAdminUserId, userId)
                .eq(Product::getId, productId));
        if (count.equals(0L)){  //是否为商品创建者
            Long count2 = proxyMapper.selectCount(new LambdaQueryWrapper<ProxyProduct>().eq(ProxyProduct::getProductId, productId)
                    .eq(ProxyProduct::getUserid, userId));
            if (count2.equals(0L)){ //是否为商品代理人
                return false;
            }
        }
        return true;
    }


    /**
     * @author 吴键霏
     * @description 缓存预热与过滤器初始化
     * @createDate 2024-06-17 19:17:30
     */

   @PostConstruct
    public void init(){
        // 商品详细信息
        List<Product> products = productMapper.selectList(null);
        if (products==null||products.size()==0){
            return;
        }
        products.stream().forEach(product->{
            // 供应商服务信息
            Server server = serverMapper.selectOne(new LambdaQueryWrapper<Server>().eq(Server::getProductId, product.getId()));
            // 商品购买方式类型信息
            LambdaQueryWrapper<Price> priceQueryWrapper=new LambdaQueryWrapper<>();
            priceQueryWrapper.eq(Price::getProductId,product.getId());
            priceQueryWrapper.select(Price::getId,Price::getScore,Price::getMoney,Price::getProductId,Price::getCreateTime);
            List<Price> priceTypeList = priceMapper.selectList(priceQueryWrapper);
            // 封装返回数据
            ProductDetailsQueryVO productDetailsQueryVO = new ProductDetailsQueryVO();
            // 封装供应商服务信息
            productDetailsQueryVO.setSupplier(server.getCompany());
            productDetailsQueryVO.setPhoneNumber(server.getPhoneNumber());
            productDetailsQueryVO.setServer(server.getProductServer());
            // 封装价格类型信息
            productDetailsQueryVO.setPriceTypeList(priceTypeList);
            // 封装商品基本信息
            BeanUtils.copyProperties(product,productDetailsQueryVO);
            // 写入redis
            Long timeout= RandomUtil.randomLong(3,7);
            redisTemplate.opsForValue().set("productDetails:" + product.getId(),JSONUtil.toJsonStr(productDetailsQueryVO),
                    timeout,TimeUnit.DAYS);
            // 写入布隆过滤器
            BloomUtil.bloomFilter.put(product.getId());
        });
    }

    /**
     * @author 吴键霏
     * @description 商品详细信息查询
     * @createDate 2024-06-17 19:17:30
     */
    @Override
    public Result<ProductDetailsQueryVO> productDetailsById(Long productId) {
        // 布隆过滤器
        if (!BloomUtil.bloomFilter.mightContain(productId)){
            return Result.error("非法商品，不存在");
        }
        // 获取登入用户信息
        Long userId= UserContext.getUser().getId();
        int role=UserContext.getUser().getRole();
        if (role!= AuthenticationConstant.SUPER_ADMIN){
            Long count = productMapper.selectCount(new LambdaQueryWrapper<Product>().eq(Product::getId, productId)
                    .eq(Product::getAdminUserId, userId));
            if (count==null||count==0){
                Long count2 = proxyMapper.selectCount(new LambdaQueryWrapper<ProxyProduct>().eq(ProxyProduct::getProductId, productId)
                        .eq(ProxyProduct::getUserid, userId));
                if (count2==null||count==0){
                    return Result.error("没有权限查询");
                }
            }
        }
        ProductDetailsQueryVO productDetailsQueryVO=null;
        // 判断缓存中是否有该数据
        String jsonData = redisTemplate.opsForValue().get("productDetails:" + productId);
        if (jsonData!=null){
            productDetailsQueryVO = JSONUtil.toBean(jsonData, ProductDetailsQueryVO.class);
            return Result.success(productDetailsQueryVO);
        }
        // 缓存中没有该数据时,查询数据库
        // 商品基本信息,todo 有多余数据待优化
//        LambdaQueryWrapper<Product> queryWrapper=new LambdaQueryWrapper<>();
        Product product = productMapper.selectById(productId);
        if (product==null){
            // 数据库也没有该商品数据
            // 设置缺省值
            redisTemplate.opsForValue().set("productDetails:" + productId,JSONUtil.toJsonStr(new ProductDetailsQueryVO()),
                    1L, TimeUnit.MINUTES);
            return Result.error("没有该商品信息");
        }
        // 供应商服务信息
        Server server = serverMapper.selectOne(new LambdaQueryWrapper<Server>().eq(Server::getProductId, productId));
        // 商品购买方式类型信息
        LambdaQueryWrapper<Price> priceQueryWrapper=new LambdaQueryWrapper<>();
        priceQueryWrapper.eq(Price::getProductId,productId);
        priceQueryWrapper.select(Price::getId,Price::getScore,Price::getMoney,Price::getProductId,Price::getCreateTime);
        List<Price> priceTypeList = priceMapper.selectList(priceQueryWrapper);
        // 封装返回数据
        productDetailsQueryVO = new ProductDetailsQueryVO();
        // 封装供应商服务信息
        productDetailsQueryVO.setSupplier(server.getCompany());
        productDetailsQueryVO.setPhoneNumber(server.getPhoneNumber());
        productDetailsQueryVO.setServer(server.getProductServer());
        // 封装价格类型信息
        productDetailsQueryVO.setPriceTypeList(priceTypeList);
        // 封装商品基本信息
        BeanUtils.copyProperties(product,productDetailsQueryVO);
        // 回写
        Long timeout= RandomUtil.randomLong(3,7);
        redisTemplate.opsForValue().set("productDetails:" + productId,JSONUtil.toJsonStr(productDetailsQueryVO),
                timeout, TimeUnit.DAYS);
        return Result.success(productDetailsQueryVO);
    }

    /**
     * @author 吴键霏
     * @description 商品分页查询
     * @createDate 2024-06-17 10:48:34
     */
    @Override
    public Result<PageVO<ProductQueryVO>> productPageQuery(Long page, Long size, ProductQueryDTO productQueryDTO) {
        LambdaQueryWrapper<Product> productQueryWrapper=new LambdaQueryWrapper<>();
        LambdaQueryWrapper<ProxyProduct> proxyProductQueryWrapper=new LambdaQueryWrapper<>();
        Page<Product> productPage=new Page<>(page,size);
        // 获取登入用户信息
        Long userId=UserContext.getUser().getId();
        int role=UserContext.getUser().getRole();
        // 不为空时才进入条件筛选
        if(productQueryDTO!=null){
            // 是否有根据商品id寻找
            if (productQueryDTO.getId()!=null){
                PageVO<ProductQueryVO> pageVO = new PageVO<>();
                pageVO.setTotal(1L);
                List<ProductQueryVO> records=new ArrayList<>();
                Product product = productMapper.selectById(productQueryDTO.getId());
                if (product==null){
                    return Result.error("没有该商品");
                }
                proxyProductQueryWrapper.eq(ProxyProduct::getProductId,product.getId()).eq(ProxyProduct::getUserid,userId);
                ProxyProduct proxyProduct = proxyMapper.selectOne(proxyProductQueryWrapper);
                proxyProductQueryWrapper.clear();
                if (product.getAdminUserId()!=userId&&proxyProduct==null&&role!=AuthenticationConstant.SUPER_ADMIN){
                    return Result.error("没有权限查询该商品");
                }
                ProductQueryVO productQueryVO = new ProductQueryVO();
                BeanUtils.copyProperties(product,productQueryVO);
                // rpc 调用 用户名设置
                UserVO user = userService.getByUserId(product.getAdminUserId());
                productQueryVO.setAdminUser(user.getUserName());
                records.add(productQueryVO);
                pageVO.setRecord(records);
                return Result.success(pageVO);
            }
            // 产品名
            if (productQueryDTO.getName()!=null){
                // 模糊匹配
                productQueryWrapper.like(Product::getName,productQueryDTO.getName());
            }
            // 上下线日期
            if (productQueryDTO.getOnlineTime()!=null){
                LocalDateTime onlineDateTime = productQueryDTO.getOnlineTime().with(LocalTime.MIN);
                productQueryWrapper.ge(Product::getOnlineTime,onlineDateTime);
            }
            if (productQueryDTO.getDownlineTime()!=null){
                LocalDateTime downlineDateTime=productQueryDTO.getDownlineTime().with(LocalTime.MAX);
                // 没有下线日期的不会被包含
                productQueryWrapper.le(Product::getDownlineTime,downlineDateTime);
            }
            // 状态
            if (productQueryDTO.getStatus()!=null){
                productQueryWrapper.eq(Product::getStatus,productQueryDTO.getStatus());
            }
        }

        // 防止报空指针异常
        if (productQueryDTO==null){
            productQueryDTO=new ProductQueryDTO();
        }
        // 判断用户角色如果为超级管理员才能筛选任意指定人的商品
        if (role==AuthenticationConstant.SUPER_ADMIN && productQueryDTO.getAdminUserId()!=null){
            productQueryWrapper.eq(Product::getAdminUserId,productQueryDTO.getAdminUserId());
        }
        // 创建者和代理者

        // 小二只能筛选本人及代理产品的指定人的产品
        if (role==AuthenticationConstant.ADMIN && productQueryDTO.getAdminUserId()!=null){
            if (productQueryDTO.getAdminUserId().equals(userId)){// 指定人是自己
                productQueryWrapper.eq(Product::getAdminUserId,userId);
            }else {
                // 获取有权限查询的所有其代理产品的id
                List<Long> ids = productMapper.Ids(productQueryDTO.getAdminUserId(), userId);
                productQueryWrapper.in(Product::getId,ids);
            }
        }

        // 判断用户角色如果为小二只能查询自己的
        if (role==AuthenticationConstant.ADMIN && productQueryDTO.getAdminUserId()==null){

            // 从代理人-商品表中查出商品ids
            proxyProductQueryWrapper.eq(ProxyProduct::getUserid,userId);
            // 查询 "productIds"
            proxyProductQueryWrapper.select(ProxyProduct::getProductId);
            List<ProxyProduct> proxyProducts = proxyMapper.selectList(proxyProductQueryWrapper);

            // 查询商品信息
            if (proxyProducts!=null && proxyProducts.size()>0){
                List<Long> productIds = proxyProducts.stream().map(item -> item.getProductId()).collect(Collectors.toList());
                // 形成 a and b and c and（d or e）
                // 代理人商品+自己商品
                productQueryWrapper.and(wrapper->wrapper.eq(Product::getAdminUserId,userId).or().in(Product::getId,productIds));
            }
        }
        // 查询"id", "name", "number", "onLineTime", "downLineTime", "status", "adminUserId"
        productQueryWrapper.select(Product::getId,Product::getName,Product::getNum,
                Product::getOnlineTime,Product::getDownlineTime,Product::getStatus,Product::getAdminUserId);
        try {
            productMapper.selectPage(productPage,productQueryWrapper);
        }catch (Exception e){
            return Result.error("查询结果失败，请重试");
        }
        // 封装返回数据
        PageVO<ProductQueryVO> pageVO = new PageVO<>();
        pageVO.setTotal(productPage.getTotal());
        List<ProductQueryVO> records=new ArrayList<>();

        List<Long> ids=new ArrayList<>();
        if (productPage.getRecords()==null||productPage.getRecords().size()==0){
            return Result.error("没有相应商品数据");
        }
        productPage.getRecords().stream().forEach(item->{
            ProductQueryVO productQueryVO = new ProductQueryVO();
            BeanUtils.copyProperties(item,productQueryVO);
            records.add(productQueryVO);
            ids.add(item.getAdminUserId());
        });
        // rpc 调用 用户名查询并封装
        List<User> users = userService.getByUserIds(ids);
        Map<Long,String> nameMap=new HashMap<>();
        users.forEach(item->{
            nameMap.put(item.getId(),item.getUserName());
        });
        records.forEach(item->{
            item.setAdminUser(nameMap.get(item.getId()));
        });
        pageVO.setRecord(records);
        return Result.success(pageVO);
    }


    @Override
    //商品请求审核
    public Result verifyRequest(Long productId) {
        if (UserContext.getUser().getRole() == AuthenticationConstant.SUPER_ADMIN) {
            return Result.error("抱歉，管理员无法发起审核");
        }
        //权限校验
        boolean flag = IDCheck(productId);
        if(! flag) {
            return Result.error("抱歉，您暂无权限操作该商品");
        }

        if (productId == null) {
            return Result.error("无商品信息");
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime updateTime = LocalDateTime.now();
        String time = updateTime.format(dateTimeFormatter);
        if (productMapper.checking(productId, time) > 0) {
            return Result.success();
        }else {
            return Result.error("操作失败");
        }
    }

    @Override
    //审核通过
    public Result verifyPass(Long productId) {
        if (UserContext.getUser().getRole() != AuthenticationConstant.SUPER_ADMIN) {
            return Result.error("抱歉，您暂无权限操作");
        }
        if (productId == null) {
            return Result.error("无商品信息");
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime updateTime = LocalDateTime.now();
        String time = updateTime.format(dateTimeFormatter);
        if (productMapper.passCheck(productId, time) > 0) {
            return Result.success();
        }else {
            return Result.error("操作失败");
        }
    }

    @Override
    //审核不通过
    public Result verifyUnpass(Long productId) {
        if (UserContext.getUser().getRole() != AuthenticationConstant.SUPER_ADMIN) {
            return Result.error("抱歉，您暂无权限操作该商品");
        }
        if (productId == null) {
            return Result.error("无商品信息");
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime updateTime = LocalDateTime.now();
        String time = updateTime.format(dateTimeFormatter);
        if (productMapper.unPass(productId, time) > 0) {
            return Result.success();
        }else {
            return Result.error("操作失败");
        }
    }

    // 上下线
    @Override
    public Result line(Long productId, Integer status) {
        //权限校验
        boolean flag = IDCheck(productId);
        if(! flag) {
            return Result.error("抱歉，您暂无权限操作该商品");
        }

        if (productId == null) {
            return Result.error("无商品信息");
        }
        LambdaUpdateWrapper<Product> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(Product::getId, productId);
        if (status == 4) {
            //上线请求，在审核通过的情况下上线
            lambdaUpdateWrapper.eq(Product::getStatus, 2)
                    .set(Product::getStatus, status)
                    .set(Product::getOnlineTime, LocalDateTime.now())
                    .set(Product::getUpdateTime, LocalDateTime.now());
        }else if(status == 5) {
            //下线请求，在上线的情况下下线
            lambdaUpdateWrapper.eq(Product::getStatus, 4)
                    .set(Product::getStatus, status)
                    .set(Product::getDownlineTime, LocalDateTime.now())
                    .set(Product::getUpdateTime, LocalDateTime.now());
        }else {
            return Result.error("非法操作");
        }
        if( productMapper.update(null, lambdaUpdateWrapper) > 0) {
            if(status==4)
            {
                //发送定时任务 定时下线
                log.info("商品上线成功，准备发定时下线任务");
                Product product=productMapper.selectById(productId);
                LocalDateTime downLineTime = product.getDownlineTime();
                // 获取时间差值
                LocalDateTime now = LocalDateTime.now();
                Duration duration = Duration.between(now, downLineTime);
                long seconds = duration.getSeconds();
                long absoluteSeconds = Math.abs(seconds);
                scheduleProductShutdown(product,absoluteSeconds);

            }

            return Result.success();
        }else {
            return Result.error("操作失败");
        }
    }
    public void scheduleProductShutdown(Product product, long ttlInSeconds) {
        // 设置消息的TTL（以毫秒为单位）
        long ttlInMillis = TimeUnit.SECONDS.toMillis(ttlInSeconds);

        // 使用MessagePostProcessor来设置消息的TTL
        rabbitTemplate.convertAndSend("original.exchange", "downLine", product, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setExpiration(String.valueOf(ttlInMillis));
                return message;
            }
        });

        log.info("商品上线成功，发送定时下线任务，TTL为{}秒", ttlInSeconds);
    }
    @Override
    public void downLine(Product product) {
        Long productId = product.getId();
        Product currentProduct=productMapper.selectById(productId);
        LocalDateTime downLineTime=product.getDownlineTime();
        LocalDateTime currentDownLineTime = currentProduct.getDownlineTime();
        if(downLineTime.equals(currentDownLineTime))
        {
            product.setStatus(5);
            productMapper.updateById(product);
        }

    }

    @Override
    public void productOnAndDownLine() {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 4);
        //挑选所有上线商品
        List<Product> productList=productMapper.selectList(queryWrapper);
        LocalDateTime time=LocalDateTime.now();
        Long count=0L;
        for(Product product:productList){
            //根据当前时间判断是否该下线
            if(product.getDownlineTime().isBefore(time)){
                    product.setStatus(5);
                    productMapper.updateById(product);
                    count++;
            }
        }
        System.out.println("本次下线商品"+count+"个   "+time);
        queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 2);
        //挑选所有状态为通过审核的商品
        productList=productMapper.selectList(queryWrapper);
        count=0L;
        for(Product product:productList){
            //根据当前时间判断是否该上线
            if(product.getOnlineTime().isAfter(time)){
                product.setStatus(4);
                productMapper.updateById(product);
                count++;
            }
        }
        System.out.println("本次上线商品"+count+"个   "+time);
    }

    //判断当前登录用户能否操作对应的商品
    private boolean IDCheck(Long productId) {
        if(UserContext.getUser().getRole() == AuthenticationConstant.SUPER_ADMIN) {
            return true;
        }
        //判断当前商品是否归当前用户管控
        //查询商品所关联的代理人信息
        QueryWrapper<ProxyProduct> proxyProductQueryWrapper = new QueryWrapper<>();
        proxyProductQueryWrapper.eq("productId", productId);
        List<ProxyProduct> proxyProducts = proxyMapper.selectList(proxyProductQueryWrapper);
        //查询当前商品的adminUserId
        Product product = productMapper.selectById(productId);
        ArrayList<Long> ids = new ArrayList<>();

        //将能操作该商品的管理者的id封装在一起
        for (ProxyProduct proxyProduct: proxyProducts) {
            ids.add(proxyProduct.getUserid());
        }
        ids.add(product.getAdminUserId());
        //身份判断
        Long userId = UserContext.getUser().getId();
        for (Long id: ids) {
            if (Objects.equals(userId, id)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Long getAdminUserIdByProductId(Long productId) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", productId);
        return productMapper.selectOne(queryWrapper).getAdminUserId();
    }

    @Override
    @Transactional
    public Result addProductAndPrice(ProductAddDTO productAddDTO) {
        //根据当前用户id添加，不存在干扰
        Product product=new Product();                       //从productAddDTO中提取Product信息
        LocalDateTime time=LocalDateTime.now();
        BeanUtils.copyProperties(productAddDTO,product);
        product.setSendAddress(productAddDTO.getSendAddress().toString());
        product.setUnsendAddress(productAddDTO.getUnsendAddress().toString());
        product.setCreateTime(time);
        product.setAdminUserId(UserContext.getUser().getId());

        Server server=new Server();                                //提取服务信息
        BeanUtils.copyProperties(productAddDTO,server);
        server.setCreateTime(time);

        List<Price> priceList=productAddDTO.getPriceList();     //提取商品价格列表

        if(product.getName() == null || StringUtils.isBlank(product.getName())){
            throw new ShuMaException(MessageConstant.PRODUCT_NAME_NULL);
        }
        if(product.getDescribes() == null || StringUtils.isBlank(product.getDescribes())){
            throw new ShuMaException(MessageConstant.PRODUCT_DESCRIBES_NULL);
        }
        if(product.getDetails() == null || StringUtils.isBlank(product.getDetails())){
            throw new ShuMaException(MessageConstant.PRODUCT_DETAILS_NULL);
        }
        if(product.getType() == null || StringUtils.isBlank(product.getType())){
            throw new ShuMaException(MessageConstant.PRODUCT_TYPE_NULL);
        }
        if(product.getClassName() == null || StringUtils.isBlank(product.getClassName())){
            throw new ShuMaException(MessageConstant.PRODUCT_CLASSNAME_NULL);
        }
        if(product.getNum()<=0){
            throw new ShuMaException(MessageConstant.PRODUCT_NUM_ERROR);
        }
        if(product.getLimits()<=0){
            throw new ShuMaException(MessageConstant.PRODUCT_LIMITS_ERROR);
        }
        if(product.getOnlineTime().isAfter(product.getDownlineTime())){
            throw new ShuMaException(MessageConstant.ONLINETIME_AFTER_DOWNLINETIME);
        }
        if(product.getDownlineTime().isBefore(LocalDateTime.now())){
            throw new ShuMaException(MessageConstant.DOWNLINETIME_BEFORE_NOW);
        }
        if(product.getOnlineTime().isBefore(LocalDateTime.now())){
            throw new ShuMaException(MessageConstant.ONLINETIME_BEFORE_NOW);
        }

        for(Price price:priceList) {
            int priceType=price.getPriceType();
            switch (priceType){
                case 1:
                    if(price.getMoney()!=0){
                        throw new ShuMaException(MessageConstant.SCORES_ONLY_ERROR);
                    }
                    if(price.getScore()==0){
                        throw new ShuMaException(MessageConstant.SCORES_ZERO_ERROR);
                    }
                    break;
                case 2:
                    if(price.getMoney()==0){
                        throw new ShuMaException(MessageConstant.MONEY_ZERO_ERROR);
                    }
                    if(price.getScore()==0){
                        throw new ShuMaException(MessageConstant.SCORES_ZERO_ERROR);
                    }
                    break;
                case 3:
                    if(price.getScore()!=0){
                        throw new ShuMaException(MessageConstant.MONEY_ONLY_ERROR);
                    }
                    if(price.getMoney()==0){
                        throw new ShuMaException(MessageConstant.MONEY_ZERO_ERROR);
                    }
                    break;
                default:
                    throw new ShuMaException(MessageConstant.ILLEGAL_PRICETYPE_ERROR);
            }
            if(price.getScore()<0||price.getMoney()<0){
                throw new ShuMaException(MessageConstant.NEGATIVE_ERROR);
            }
        }

        if(server.getCompany() == null || StringUtils.isBlank(server.getCompany())){
            throw new ShuMaException(MessageConstant.PRODUCT_COMPANY_NULL);
        }
        if(server.getProductServer() == null || StringUtils.isBlank(server.getProductServer())){
            throw new ShuMaException(MessageConstant.PRODUCT_PRODUCTSERVER_NULL);
        }
        if(server.getPhoneNumber() == null || StringUtils.isBlank(server.getPhoneNumber())){
            throw new ShuMaException(MessageConstant.PRODUCT_PHONENUMBER_NULL);
        }
        product.setStatus(0);                              //新增商品默认为0
        save(product);
        for(Price price:priceList) {
            price.setCreateTime(time);                    //设置创建时间
            price.setProductId(product.getId());          //设置商品id
        }
        priceService.saveBatch(priceList);
        server.setProductId(product.getId());
        serverService.save(server);
//        product.setServerId(server.getId());
        updateById(product);
        scratchpadService.deleteScratchpadByUserId();  //商品上传时当前用户的草稿清空
        //将新建商品信息写入redis
        ProductDetailsQueryVO productDetailsQueryVO = new ProductDetailsQueryVO();
        // 封装供应商服务信息
        productDetailsQueryVO.setSupplier(server.getCompany());
        productDetailsQueryVO.setPhoneNumber(server.getPhoneNumber());
        productDetailsQueryVO.setServer(server.getProductServer());
        // 封装价格类型信息
        productDetailsQueryVO.setPriceTypeList(priceList);
        // 封装商品基本信息
        BeanUtils.copyProperties(product,productDetailsQueryVO);
        // 写入redis
        Long timeout= RandomUtil.randomLong(3,7);
        redisTemplate.opsForValue().set("productDetails:" + product.getId(),JSONUtil.toJsonStr(productDetailsQueryVO),
                timeout,TimeUnit.DAYS);
        BloomUtil.bloomFilter.put(product.getId());
        return Result.success();

    }

    @Override
    @Transactional
    public Result updateProductAndPrice(ProductEditDTO productEditDTO) {
        if (!BloomUtil.bloomFilter.mightContain(productEditDTO.getId())){
            throw new ShuMaException(MessageConstant.PRODUCT_NOT_EXIST);
        }
        User user = UserContext.getUser();
        Long userId=user.getId();
        Integer role=user.getRole();
        if (role== AuthenticationConstant.ADMIN){    //管理员有权更新
            // 验证权限
            boolean authority = haveAuthority(productEditDTO.getId(), userId);   //创建者和代理人有权更新
            if (!authority){
                throw new ShuMaException(MessageConstant.LOW_PERMISSION);
            }
        }
        Product product=new Product();                       //从productEditDTO中提取Product信息
        BeanUtils.copyProperties(productEditDTO,product);
        product.setUpdateTime(LocalDateTime.now());
        product.setSendAddress(productEditDTO.getSendAddress().toString());
        product.setUnsendAddress(productEditDTO.getUnsendAddress().toString());
        product.setAdminUserId(UserContext.getUser().getId());

        Server server=new Server();                                //提取服务信息
        BeanUtils.copyProperties(productEditDTO,server);
        server.setCreateTime(LocalDateTime.now());
        server.setId(serverService.getIdByProductId(product.getId()));
        server.setProductId(productEditDTO.getId());

        List<Price> priceList=productEditDTO.getPriceList();     //提取商品价格列表

        if(product.getName() == null || StringUtils.isBlank(product.getName())){
            throw new ShuMaException(MessageConstant.PRODUCT_NAME_NULL);
        }
        if(product.getDescribes() == null || StringUtils.isBlank(product.getDescribes())){
            throw new ShuMaException(MessageConstant.PRODUCT_DESCRIBES_NULL);
        }
        if(product.getDetails() == null || StringUtils.isBlank(product.getDetails())){
            throw new ShuMaException(MessageConstant.PRODUCT_DETAILS_NULL);
        }
        if(product.getType() == null || StringUtils.isBlank(product.getType())){
            throw new ShuMaException(MessageConstant.PRODUCT_TYPE_NULL);
        }
        if(product.getClassName() == null || StringUtils.isBlank(product.getClassName())){
            throw new ShuMaException(MessageConstant.PRODUCT_CLASSNAME_NULL);
        }
        if(product.getNum()<=0){
            throw new ShuMaException(MessageConstant.PRODUCT_NUM_ERROR);
        }
        if(product.getLimits()<=0){
            throw new ShuMaException(MessageConstant.PRODUCT_LIMITS_ERROR);
        }
        if(product.getOnlineTime().isAfter(product.getDownlineTime())){
            throw new ShuMaException(MessageConstant.ONLINETIME_AFTER_DOWNLINETIME);
        }
        if(product.getDownlineTime().isBefore(LocalDateTime.now())){
            throw new ShuMaException(MessageConstant.DOWNLINETIME_BEFORE_NOW);
        }
        if(product.getOnlineTime().isBefore(LocalDateTime.now())){
            throw new ShuMaException(MessageConstant.ONLINETIME_BEFORE_NOW);
        }

        for(Price price:priceList) {
            int priceType=price.getPriceType();
            switch (priceType){
                case 1:
                    if(price.getMoney()!=0){
                        throw new ShuMaException(MessageConstant.SCORES_ONLY_ERROR);
                    }
                    if(price.getScore()==0){
                        throw new ShuMaException(MessageConstant.SCORES_ZERO_ERROR);
                    }
                    break;
                case 2:
                    if(price.getMoney()==0){
                        throw new ShuMaException(MessageConstant.MONEY_ZERO_ERROR);
                    }
                    if(price.getScore()==0){
                        throw new ShuMaException(MessageConstant.SCORES_ZERO_ERROR);
                    }
                    break;
                case 3:
                    if(price.getScore()!=0){
                        throw new ShuMaException(MessageConstant.MONEY_ONLY_ERROR);
                    }
                    if(price.getMoney()==0){
                        throw new ShuMaException(MessageConstant.MONEY_ZERO_ERROR);
                    }
                    break;
                default:
                    throw new ShuMaException(MessageConstant.ILLEGAL_PRICETYPE_ERROR);
            }
            if(price.getScore()<0||price.getMoney()<0){
                throw new ShuMaException(MessageConstant.NEGATIVE_ERROR);
            }
        }

        if(server.getCompany() == null || StringUtils.isBlank(server.getCompany())){
            throw new ShuMaException(MessageConstant.PRODUCT_COMPANY_NULL);
        }
        if(server.getProductServer() == null || StringUtils.isBlank(server.getProductServer())){
            throw new ShuMaException(MessageConstant.PRODUCT_PRODUCTSERVER_NULL);
        }
        if(server.getPhoneNumber() == null || StringUtils.isBlank(server.getPhoneNumber())){
            throw new ShuMaException(MessageConstant.PRODUCT_PHONENUMBER_NULL);
        }
        product.setStatus(0);                              //商品修改后重新审核
        updateById(product);
        serverService.updateById(server);
        Map<String,Object> map=new HashMap<>();          //更新商品价格信息(先删再插)
        map.put("productId",product.getId());
        priceService.removeByMap(map);
        for(Price price:priceList) {
            if (price.getCreateTime() == null) {                     //根据传入创建时间，判断价格是新增还是已存在
                price.setCreateTime(LocalDateTime.now());            //设置创建时间
            } else {
                price.setUpdateTime(LocalDateTime.now());            //设置更新时间
            }
            price.setProductId(product.getId());          //设置商品id
        }
        priceService.saveBatch(priceList);

        // 删除Redis的缓存数据，利用回写机制来实现最终一致性
        redisTemplate.delete("productDetails:" + product.getId());
        return Result.success();
    }

}





